from QSizer import QSizer, QSizerGet, ObjectHeightGet, ObjectWidthGet, ObjectPosSizeSet
from Cube.gui.DirectGUIPropertiesAccess import ScaleGet as FrameScaleGet

class BoxSizer(QSizer):
    # orient at __init__()
    VERTICAL = 0    # grows to bottom
    HORIZONTAL = 1  # grows to right

    def __init__(self, orient = 0, **kw):
        QSizer.__init__(self,**kw)
        self.Orient = orient  # QSizer.VERTICAL or QSizer.HORIZONTAL
        self.Gap = kw.get("gap",0)

    def Layout(self):
        # does outer information available?
        if (not self.pos) or (not self.size):
            raise "BoxSizer Can not layout Sizer"

        self.PropertySet()
        SlotList = self.SlotList

        # get actual size
        remainderLength = self._RemainderLength - (self.Gap*(len(SlotList)-1))
        for item in SlotList:
            if item["proportion"]==0:
                actualSize = self.ActualSizeGet(item["guiObject"])
                item["actualSize"] = actualSize
                remainderLength -= actualSize
        self._RemainderLength = remainderLength
        # get unit length from remainder length
        denominator = sum( [item["proportion"] for item in SlotList] )
        self._unitLength = float(remainderLength)/denominator if denominator else 0
        if self._unitLength < 0:
            print "Unit Length of QSize should > 0" # error
            self._unitLength = 0

        # set object size
        for item in SlotList: self.PosSizeSet(item)

        # call Sizer.Layout
        for item in SlotList:
            sizer = QSizerGet(item["guiObject"])
            if sizer: sizer.Layout()

    def SizerHightGet(self):
        if self.Orient == BoxSizer.HORIZONTAL:
            ret = max([ObjectHeightGet(item["guiObject"]) for item in self.SlotList])
        else: #BoxSizer.VERTICAL
            ret = sum([ObjectHeightGet(item["guiObject"]) for item in self.SlotList]) \
                  + (self.Gap*(len(self.SlotList)-1))
        return ret

    def SizerWidthGet(self):
        if sizer.Orient == BoxSizer.HORIZONTAL:
            ret = sum([ObjectWidthGet(item["guiObject"]) for item in self.SlotList]) \
                  + (self.Gap*(len(self.SlotList)-1))
        else: #BoxSizer.VERTICAL
            ret = max([ObjectWidthGet(item["guiObject"]) for item in self.SlotList])
        return ret

    def ActualSizeGet(self, item):
        if self.Orient == BoxSizer.HORIZONTAL:
            ret = ObjectWidthGet(item)
        else: #BoxSizer.VERTICAL
            ret = ObjectHeightGet(item)
        return ret

    def PropertySet(self):
        self._LeftX, self._RightX, self._BottomZ, self._TopZ = QSizer.BoundaryGet(self)
        self._TopBound, self._LeftBound = self._TopZ, self._LeftX
        if self.Orient == BoxSizer.HORIZONTAL:
            self._RemainderLength = self._RightX - self._LeftX
        else: #BoxSizer.VERTICAL
            self._RemainderLength = self._TopZ - self._BottomZ

    def PosSizeSet(self, item):
        # set object.pos and object.size
        guiObject,proportion,flag = item["guiObject"],item["proportion"],item["flag"]
        objectLength = (proportion*self._unitLength) if proportion else item["actualSize"]

        if self.Orient == BoxSizer.HORIZONTAL:
            currRightX = self._LeftBound + objectLength
            sizerBoundXZ = (self._LeftBound, currRightX, self._BottomZ, self._TopZ)
            flagXZ = (QSizer.EXPAND, flag)
            ObjectPosSizeSet(guiObject, sizerBoundXZ, flagXZ)
            self._LeftBound = currRightX + self.Gap
        else: #BoxSizer.VERTICAL
            currBottomZ = self._TopBound - objectLength
            sizerBoundXZ = (self._LeftX, self._RightX, currBottomZ, self._TopBound)
            flagXZ = (flag, QSizer.EXPAND)
            ObjectPosSizeSet(guiObject, sizerBoundXZ, flagXZ)
            self._TopBound = currBottomZ - self.Gap

